<template>
  <view class="spec-box">
    <view v-for="(spec, specIndex) in specList" :key="specIndex" class="spec-item">
      <view class="spec-label">{{ spec.name }}</view>
      <view class="value-box">
        <view
            v-for="(attribute, attributeIndex) in spec.values"
            :key="attributeIndex"
            :class="{
            active: curChoose[specIndex] === attribute,
            disable: !canChooseSpecs.includes(attribute)
          }"
            class="value-item"
            @click="handleAttributeClick(attribute, specIndex)"
        >
          <xl-image
              v-if="spec.isImage && spec.images[attributeIndex]"
              :src="spec.images[attributeIndex]"
              border-radius="28rpx"
              height="56rpx"
              width="56rpx"
          ></xl-image>
          <view class="text">{{ attribute }}</view>
        </view>
      </view>
    </view>
  </view>
</template>

<script setup>
import {computed, ref, watch} from 'vue'
import propsData from './props.js'

const props = defineProps(propsData)

const emits = defineEmits(['change', 'product'])

// 选中盒子背景颜色
const activeBgColor = computed(() => uni.$xl.color.colorToRgba(props.color, 0.08))

// 规格项列表
const specList = ref([])
// 规格邻接矩阵
let goodsSpecsMatrix = null
// 当前可选规格项
const canChooseSpecs = ref([])
// 当前已选规格
const curChoose = ref([])

// 规格数据
const specData = computed(() => {
  return {specList: props.specList, skuList: props.skuList}
})
// 监听规格数据变化
watch(() => specData.value, newVal => {
  canChooseSpecs.value = []
  curChoose.value = []
  let isImage = false
  specList.value = specData.value.specList.map((spec, index) => {
    curChoose.value[index] = ''
    spec.values = spec.values.map(attr => {
      if (typeof attr === 'string') {
        return attr
      }
      if (!isImage) {
        isImage = true
        spec.isImage = true
        spec.images = []
      }
      if (spec.isImage) {
        spec.images.push(attr[props.imageName])
      }
      return attr.value
    })

    return spec
  })
  // 创建邻接矩阵
  goodsSpecsMatrix = uni.$xl.specs.createSpecsMatrix(specData.value.specList, specData.value.skuList)
  // 获得可选项表
  canChooseSpecs.value = goodsSpecsMatrix.getSpecscOptions()
  // 设置默认选中
  setDefaultChoose()
}, {immediate: true, deep: false})

watch(() => props.curSpec, newVal => {
  setDefaultChoose()
})

// 设置默认选中 默认为第一个可选项
function setDefaultChoose() {
  if (props.curSpec) {
    curChoose.value = props.curSpec
    canChooseSpecs.value = goodsSpecsMatrix.getSpecscOptions(curChoose.value)
    specChange()
  } else {
    // 设置可选
    let end = false
    curChoose.value = specList.value.reduce((result, cur) => {
      if (end) {
        return result
      }
      let find = cur.values.find(v => canChooseSpecs.value.includes(v))
      if (find) {
        result.push(find)
        canChooseSpecs.value = goodsSpecsMatrix.getSpecscOptions(result)
      } else {
        end = true
      }
      return result
    }, [])
    specChange()
  }
}

function handleAttributeClick(attribute, spceIndex) {
  console.log()
  // 排除可选规格里面没有的规格
  if (!canChooseSpecs.value.includes(attribute)) return
  // 根据text判断是否已经被选中了
  curChoose.value[spceIndex] = curChoose.value[spceIndex] === attribute ? '' : attribute
  // 重新获得可选项
  canChooseSpecs.value = goodsSpecsMatrix.getSpecscOptions(curChoose.value)
  // 触发事件
  specChange()
}

// 规格变化
function specChange() {
  // 产品
  let product = null
  let productList = []
  let all = false
  let none = true
  let choose = []
  let unChoose = []

  specList.value.forEach((spec, index) => {
    if (curChoose.value[index]) {
      choose.push(spec.name)
    } else {
      unChoose.push(spec.name)
    }
  })

  if (curChoose.value.length) {
    none = false
    productList = props.skuList.filter(product => isChooseSpecProduct(product.spec, curChoose.value))
  }
  if (curChoose.value.filter(v => v).length === specList.value.length) {
    all = true
    product = productList[0]
  }
  let image = product?.[props.imageName]
  if (!image) {
    let imageIdx = specList.value.findIndex(v => v.isImage)
    if (imageIdx !== -1 && curChoose.value[imageIdx]) {
      let spec = specList.value[imageIdx]
      let valueIdx = spec.values.findIndex(v => v === curChoose.value[imageIdx])
      image = spec.images[valueIdx]
    }

  }
  emits('change', {
    value: curChoose.value,
    all,
    none,
    choose,
    unChoose,
    productList,
    product,
    image
  })
}

// 判断当前规格产品是否是当前选中
function isChooseSpecProduct(spec, choose) {
  if (!choose) {
    return false
  }
  for (let i = 0; i < choose.length; i++) {
    if (!choose[i]) continue
    if (choose[i] !== spec[i]) {
      return false
    }
  }
  return choose.filter(v => v).length > 0
}
</script>

<style lang="scss" scoped>
.spec-box {
  --color: v-bind(color);
  --active-bg-color: v-bind(activeBgColor);
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 20rpx;
}

.spec-item {
  // margin-bottom: 16rpx;
}

.spec-label {
  font-weight: 700;
  color: #333;
  font-size: 32rpx;
}

.value-box {
  display: flex;
  flex-wrap: wrap;
  padding: 30rpx 0 30rpx 16rpx;
  gap: 24rpx;
}

.value-item {
  height: 56rpx;
  background-color: #fafafa;
  border-radius: 5000px;
  display: flex;
  justify-content: center;
  align-items: center;
  //border: 1rpx solid #e5e3e3;

  &.active {
    border: 1rpx solid var(--color);
    background-color: var(--active-bg-color);
    .text {
      color: var(--color);
    }
  }

  &.disable {
    background-color: #e1e1e1;
    color: #fff;
  }

  .text {
    font-size: 28rpx;
    color: #444;
    padding: 8rpx 30rpx;
  }
}
</style>
